package com.zy.business.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.business.domain.TbRemindUser;
import com.zy.business.domain.TbVisitorInfo;
import com.zy.business.domain.TbVisitorRecord;
import com.zy.business.mapper.RemindUserMapper;
import com.zy.business.mapper.VisitorInfoMapper;
import com.zy.business.mapper.VisitorRecordMapper;
import com.zy.business.service.VisitorRecordService;
import com.zy.common.config.RuoYiConfig;
import com.zy.common.constant.CacheConstants;
import com.zy.common.core.domain.AjaxResult;
import com.zy.common.core.domain.entity.SysUser;
import com.zy.common.core.redis.RedisCache;
import com.zy.common.utils.DateUtils;
import com.zy.common.utils.StringUtils;
import com.zy.common.utils.WebUtil;
import com.zy.common.utils.file.FileUploadUtils;
import com.zy.system.mapper.*;
import com.zy.business.service.VisitorInfoService;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @description: 访客管理 服务层实现
 * @author: whf
 * @create: 2022-07-30 17:58
 **/
@Service
public class VisitorInfoServiceImpl extends ServiceImpl<VisitorInfoMapper, TbVisitorInfo> implements VisitorInfoService {

    @Resource
    private VisitorRecordMapper recordMapper;

    @Resource
    private RemindUserMapper remindUserMapper;

    @Autowired
    private VisitorRecordService recordService;

    @Resource
    private SysUserMapper userMapper;

    @Value("${APPID}")
    private String APPID;

    @Value("${APPSECRET}")
    private String APPSECRET;

    @Value("${APPLY-TEMPLATEID}")
    private String applyTemplateId;

    @Resource
    private SysDictDataMapper dictMapper;

    @Autowired
    private RedisCache redisCache;

    @Override
    public List<TbVisitorInfo> queryList(Integer type) {
        QueryWrapper<TbVisitorInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("is_black",type);
        wrapper.orderByAsc("CREATE_TIME");
        List<TbVisitorInfo> visitorInfoList = baseMapper.selectList(wrapper);
        return visitorInfoList;
    }

    @Override
    public AjaxResult getUserInfo(String openId){
        SysUser user = userMapper.getUserByOpenId(openId);
        if (user!=null){
            return AjaxResult.success(user);
        }else {
            TbVisitorInfo visitorInfo = baseMapper.selectOne(new QueryWrapper<TbVisitorInfo>().eq("open_id", openId));
            if (visitorInfo!=null){
                return AjaxResult.success(visitorInfo);
            }
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional
    public AjaxResult saveRecord(TbVisitorRecord visitorRecord) {
        try {
            /*TbVisitorInfo visitorInfo = null;
            String photoUrl = "";
            if (visitorRecord.getPhoto().indexOf(".jpg")>-1){
                photoUrl = visitorRecord.getPhoto();
            }else {
                photoUrl = downImage(visitorRecord.getPhoto());
            }*/
            /*if (visitorRecord.getVisitorId()!=null) {*/
                /*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                visitorInfo = baseMapper.selectById(visitorRecord.getVisitorId());
                QueryWrapper<TbVisitorRecord> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("visitor_id",visitorRecord.getVisitorId());
                queryWrapper.eq("state",1);
                Date beforeTime = this.delHours(sdf.format(visitorRecord.getVisitTime()), 4);
                Date behindTime = this.addHours(sdf.format(visitorRecord.getVisitTime()), 4);
                queryWrapper.and(Wrapper -> Wrapper.between("visit_time", beforeTime, visitorRecord.getVisitTime()).or().between("visit_time",visitorRecord.getVisitTime(),behindTime));
                List<TbVisitorRecord> recordList = recordMapper.selectList(queryWrapper);
                if (recordList!=null && recordList.size()>0){
                    return AjaxResult.error(503,"4小时内已有预约");
                }
                visitorInfo.setUpdateTime(new Date());
                visitorInfo.setPhone(visitorRecord.getPhone());
                if (!photoUrl.equals(visitorInfo.getPhoto())){
                    visitorInfo.setPhoto(photoUrl);
                    compression(photoUrl);
                }
                visitorInfo.setIdCard(visitorRecord.getIdCard());
                visitorInfo.setCompanyName(visitorRecord.getCompanyName());
                baseMapper.updateById(visitorInfo);*/
            /*}else {
                visitorInfo = new TbVisitorInfo();
                visitorInfo.setVisitorName(visitorRecord.getVisitorName());
                visitorInfo.setOpenId(visitorRecord.getOpenId());
                visitorInfo.setCreateTime(new Date());
                visitorInfo.setPhone(visitorRecord.getPhone());
                visitorInfo.setPhoto(photoUrl);
                visitorInfo.setIdCard(visitorRecord.getIdCard());
                visitorInfo.setCompanyName(visitorRecord.getCompanyName());
                baseMapper.insert(visitorInfo);
                compression(photoUrl);
                visitorRecord.setVisitorId(visitorInfo.getVisitorId());
            }*/
            visitorRecord.setCreateTime(new Date());
            /*if (visitorRecord.getIsReserve()==1){
                visitorRecord.setState(0);
            }*/
            recordMapper.insert(visitorRecord);
            recordService.sendMessage(visitorRecord);
            applyMessage(visitorRecord);
            /*if (visitorRecord.getIsReserve()==1){
                applyMessage(visitorRecord);
            }*/
            return AjaxResult.success();
        } catch (Exception e){
            e.printStackTrace();
        }
        return AjaxResult.error();
    }


    /**
     *
     * 当前时间增加间隔小时后的时间 时间格式 2008-08-08 16:16:34
     */
    private Date addHours(String startDate, int intHour) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = sdf.parse(startDate);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            long longMills = cal.getTimeInMillis() + intHour * 60 * 60 * 1000;
            cal.setTimeInMillis(longMills);

            // 返回日期
            return cal.getTime();
        } catch (Exception Exp) {
            return null;
        }
    }

    /**
     *
     * 当前时间减去间隔小时后的时间 时间格式 2008-08-08 16:16:34
     */
    private Date delHours(String startDate, int intHour) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = sdf.parse(startDate);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            long longMills = cal.getTimeInMillis() - intHour * 60 * 60 * 1000;
            cal.setTimeInMillis(longMills);

            // 返回日期
            return cal.getTime();
        } catch (Exception Exp) {
            return null;
        }
    }

    private void applyMessage(TbVisitorRecord record){
        List<TbRemindUser> remindUserList = remindUserMapper.selectList(new QueryWrapper<TbRemindUser>());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        //SysUser user = userMapper.selectUserById(record.getVisitUserId());
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("template_id", applyTemplateId);
        jsonObject.put("url", "http://kq.heshenghua.net/visitor/#/home?recordId="+record.getRecordId());
        /**
         * {{first.DATA}}
         * 来访姓名：{{keyword1.DATA}}
         * 来访事由：{{keyword2.DATA}}
         * 预约时间：{{keyword3.DATA}}
         * 访客电话：{{keyword4.DATA}}
         * {{remark.DATA}}
         */
        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        first.put("value", "您好，有一条新的访客预约");
        first.put("color", "#173177");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", record.getVisitorName());
        keyword1.put("color", "#173177");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", record.getVisitReason());
        keyword2.put("color", "#173177");
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", sdf.format(record.getVisitTime()));
        keyword3.put("color", "#173177");
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", record.getPhone());
        keyword4.put("color", "#173177");
        JSONObject remark = new JSONObject();
        remark.put("value", "点击查看详情");
        remark.put("color", "#173177");

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        data.put("keyword4",keyword4);
        data.put("remark",remark);

        jsonObject.put("data", data);

        if (remindUserList!=null && remindUserList.size()>0) {
            for (TbRemindUser tbRemindUser : remindUserList) {
                SysUser user = userMapper.selectUserById(tbRemindUser.getUserId());
                if (StringUtils.isNotEmpty(user.getOpenId())){
                    jsonObject.put("touser", user.getOpenId());   // openid
                    String string = null;
                    try {
                        string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    JSONObject result1 = JSONObject.parseObject(string);
                    int errcode = result1.getIntValue("errcode");
                    if(errcode == 0){
                        // 发送成功
                        System.out.println("发送成功");
                    } else {
                        // 发送失败
                        System.out.println("发送失败");
                    }
                }
            }
        }
    }

    public String downImage(String mediaId) throws IOException {
        String basePath = RuoYiConfig.getUploadPath();
        String filePath = "";
        String fileName = "";
        String accessToken = getAccessToken();
        String requestUrl = " https://api.weixin.qq.com/cgi-bin/media/get?access_token="+accessToken+"&media_id="+mediaId;
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setRequestMethod("GET");
            // 将mediaId作为文件名
            fileName = StringUtils.format("{}/{}.{}", DateUtils.datePath(),mediaId,"jpg");
            filePath = basePath + File.separator + fileName;
            BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
            File file = new File(filePath);
            if (!file.exists())
            {
                if (!file.getParentFile().exists())
                {
                    file.getParentFile().mkdirs();
                }
            }
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[8096];
            int size = 0;
            while ((size = bis.read(buf)) != -1)
                fos.write(buf, 0, size);
            fos.close();
            bis.close();
            conn.disconnect();
            String info = String.format("下载媒体文件成功，filePath=" + filePath);
            System.out.println(info);
        } catch (Exception e) {
            String error = String.format("下载媒体文件失败：%s", e);
            System.out.println(error);
        }
        return FileUploadUtils.getPathFileName(basePath,fileName);
    }

    private void compression(String imgUrl){
        String filePath = RuoYiConfig.getUploadPath() + File.separator+imgUrl;
        try {
            Thumbnails.of(filePath)
                    .scale(0.5f) //图片大小（长宽）压缩 从0按照
                    .outputQuality(0.5f) //图片质量压缩比例 从0-1，越接近1质量越好
                    .toFile(filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getAccessToken(){
        String accessToken = redisCache.getCacheObject(CacheConstants.ACCESS_TOKEN_KEY);
        if(StringUtils.isEmpty(accessToken)){
            String openUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
            JSONObject result = WebUtil.doGet(openUrl);
            accessToken = result.getString("access_token");
            Integer expiresIn = result.getInteger("expires_in");
            redisCache.setCacheObject(CacheConstants.ACCESS_TOKEN_KEY, accessToken, expiresIn, TimeUnit.SECONDS);
        }
        return accessToken;
    }

    @Override
    public AjaxResult getVisitObject() {
        List<Map<String, Object>> userList = userMapper.selectVisitUser();
        return AjaxResult.success(userList);
    }

    @Override
    public AjaxResult getOpenId(String code) {
        Map<String, Object> map = new HashMap<>();
        String openUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+APPID+"&secret="+APPSECRET+"&code="+code+"&grant_type=authorization_code";
        JSONObject result = WebUtil.doGet(openUrl);
        String openId = result.getString("openid");
        /*Integer type = 2;
        if (StringUtils.isNotEmpty(openId)){
            SysUser user = userMapper.getUserByOpenId(openId);
            if (user!=null){
                type = 1;
            }
        }
        map.put("type",type);*/
        map.put("openId",openId);
        return AjaxResult.success(map);
    }
}
